package com.yuan.blog.aop.apsect;

import com.alibaba.fastjson.JSON;
import com.yuan.blog.aop.annotation.Pv;
import com.yuan.blog.aop.type.PvType;
import com.yuan.blog.constatns.RedisKey;
import com.yuan.blog.exception.ViewException;
import com.yuan.blog.utils.ApacheHttpUtils;
import com.yuan.blog.utils.RequestUtils;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import java.util.Arrays;
import java.util.Map;
import java.util.concurrent.TimeUnit;


@Aspect // 表示这是一个切面
@Component // 这个类交给IOC容器管理
@Slf4j
public class PvAspectj {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    // 什么时候应该进入这个方法？
//    @Before("@annotation(pv)") //用户在调用加了@pv注解的方法才会进入，而且目标方法之前调用
    @Around("@annotation(pv)")
    // @Before:在目标方法之前调用
    // @annotation(pv):目标方法上面加了@pv注解的时候调用
    public Object beginRecordPv(ProceedingJoinPoint point, Pv pv) throws Throwable {


        Object[] args = point.getArgs();
        log.debug(Arrays.toString(args));
        if (pv.value().equals(PvType.INVITATION)) {
            log.debug("记录帖子的预览量");

            // 1.需要帖子id? -->如何在前置方法中获取目标方法的参数
            Integer id = (Integer) args[0];

//            // 1.查询帖子
            String json = ApacheHttpUtils.getUrl("http://localhost:8002/blog/InvitationController/InvitationInfo/"+id);
            Map invitationEntity = JSON.parseObject(json, Map.class);
            // 判断这个帖子是否被和谐了
            if(Integer.parseInt(invitationEntity.get("status").toString())==3){
                throw new ViewException(404,"帖子没有找到");
            }

            // 2.需要登录用户
//            HttpSession httpSession = (HttpSession) args[1];
//            UserE loginUser = httpSession.getAttribute("loginUser");

            // 3.判断一下当前用户是否是频繁刷新帖子
            String ip = RequestUtils.getRemoteIp();
            log.debug("ip:{}", ip);
            String ipKey = String.format(RedisKey.USER_REMOTE_IP, ip, id);
            Boolean aBoolean = stringRedisTemplate.opsForValue().setIfAbsent(ipKey, System.currentTimeMillis() + "",30, TimeUnit.SECONDS);// setnx
            // ip和id插入成功表示，这个ip是第一次访问这个帖子
            if (aBoolean) {
                // 4.记录redis
                String key = String.format(RedisKey.INVITATAION_PV, id);
                stringRedisTemplate.opsForValue().increment(key);
            }

        } else if (pv.value().equals(PvType.VIDEO)) {
            log.debug("记录视频的播放量");
        }
        return point.proceed(point.getArgs());
    }

    public static void main(String[] args) {
        String json = ApacheHttpUtils.getUrl("http://localhost:8002/blog/InvitationController/InvitationInfo/1");
        Map o = JSON.parseObject(json, Map.class);

        System.out.println(o.get("status"));
    }
}
